#include "Mainfunctions.h"
  #include <cstdlib>

const int num_objects=10; 
vector <F_Objects *> falling(num_objects);
 
Player player;
Background fondo;
Music present("../music/MainTheme.mp3"), theme("../music/CantinaBand.mp3"), endMus("../music/ImperialMarch.mp3"), saveMus("../music/ThroneRoom.mp3");

int w=850, h=550;

float difficulty=1, falling_speed=0;
float speed=0;
int prev=0, musplay=0, musend=0, musave=0;
bool loadinggame=false; 
bool titlepass=false;

void initial()
{
	string dummy; 
	//cout <<"Load last game?"<<endl; 
	//cin >> dummy; 
/*	if (dummy=="yes")
	{
		load(); 
		loadinggame=true; 
	}

	else{*/
	cout<<"Enter your name please:"<<endl;
		cin>>dummy; 
		player.setName(dummy);
	//}
}

void init(bool arcade, int difficulty)
{	
	if(arcade){
		for(int i=0; i<falling.size(); i++){
				
			if(i<1)      falling[i]= new Yoda; 
			if(i>=1 && i<2) falling[i]=new R2D2; 
			if(i>=2 && i<5) falling[i]=new Star; 
			if(i>=5)        falling[i]=new Foe; 
			
		}
		
		if (difficulty=1) falling_speed=0;
		if (difficulty=2) falling_speed=0.000001;
		if (difficulty=3) falling_speed=0.000005;


	}
	else {
		for(int i=0; i<falling.size(); i++){
			
			if(i<2) falling[i]= new R2D2;
			if(i>=2 && i<8 ) falling[i]=new Foe; 
			if(i>=8 ) falling[i]=new Star; 
		}

		if (difficulty=1) falling_speed=0;
		if (difficulty=2) falling_speed=0.00001;
		if (difficulty=3) falling_speed=0.00005;

	}
}




void juego()
{	
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glLoadIdentity();
        gluLookAt(      0.0f, 0.0f, 10.0f,
                        0.0f, 0.0f,  0.0f,
                        0.0f, 1.0f,  0.0f);
    
 	   if (prev==0){ present.play(); prev=1;}
	   if(fondo.selectscreen==Background::titlescreen ){
		fondo.title();	
	   }
	   if(fondo.selectscreen==Background::introscreen )
		fondo.introduction();
	   if(fondo.selectscreen==Background::initscreen)
		fondo.pregame();
	   if(fondo.selectscreen==Background::settingsscreen) 
		fondo.settings();
	
	   if (fondo.selectscreen==Background::arcade || fondo.selectscreen==Background::survival)
		{	
		if(player.getLife()>0 && player.getFuel()>0)
		{	
			if (musplay==0){ 
				theme.play();
				if(fondo.selectscreen==Background::arcade)
					init(true, difficulty);
				if(fondo.selectscreen==Background::survival)
					init(false, difficulty);
				musplay=1;
				
				}
			if (loadinggame)
			{
				for (int i=0; i<falling.size(); i++)
				   falling[i]->setSpeed(speed); 
			
			   	loadinggame=false; 
			}

			fondo.display();
			for (int i=0; i<falling.size(); i++)
			{
				falling[i]->display();
				falling[i]->changespeed(falling_speed); 
			}
			player.display();
			player.changeFuel(-0.01);

			for (int i=0; i<falling.size(); i++)
		 		falling[i]->collision(player); 
	
		}
		else 
			fondo.selectscreen=Background::gameover;
		}
	 
	    if(fondo.selectscreen==Background::savedplay){
			if (musave==0){ 
				saveMus.play(); 
				musave=1;
			}			
			fondo.savedScreen();
	    }

			

	   if(fondo.selectscreen==Background::gameover){
			if (musend==0){ 
				endMus.play(); 
				writeScore();
				musend=1;
			}
			fondo.gameOver(); 
				
		}
	
        glutSwapBuffers();
}



void processSpecialKeys( int key, int x, int y) {        //Función para mover al jugador: con flechas a velocidad normal, flechas+SHIFT velocidad rápida

	int i=2; // movement multiplier
	int j=10; // fuel consumption multiplier
//change when xcoor is private ok? :P				
	 switch(key){
         case GLUT_KEY_LEFT:
		if(player.getX()>=-fondo.getScreenX()+0.1){
			if(glutGetModifiers()==GLUT_ACTIVE_SHIFT){
				player.setX(player.getX()-player.despl*i);
				player.changeFuel(-0.01*j);
				}
			else {
				player.setX(player.getX()-player.despl);
			
			}	
		}
	break;

      case GLUT_KEY_RIGHT:
	 if(player.getX()<=fondo.getScreenX()-0.1){

		if(glutGetModifiers()==GLUT_ACTIVE_SHIFT){
			player.setX(player.getX()+player.despl*i);
			player.changeFuel(-0.01*j);
			}
		else {
			player.setX(player.getX()+player.despl);
		}	
	}
	break;

	 case GLUT_KEY_DOWN:
		if(player.getY()>=-fondo.getScreenY()+0.7){	
			if(glutGetModifiers()==GLUT_ACTIVE_SHIFT){
				player.setY(player.getY()-player.despl*i);
				player.changeFuel(-0.01*j);
				}
			else {
				player.setY(player.getY()-player.despl);
			}
		}	
	break;

         case GLUT_KEY_UP:
		if(player.getY()<=fondo.getScreenY()-0.9){
			if(glutGetModifiers()==GLUT_ACTIVE_SHIFT){
				player.setY(player.getY()+player.despl*i);
				player.changeFuel(-0.01*j);
				}
			else {
				player.setY(player.getY()+player.despl);

			}
		}	
	break;

         }
     
}

void processNormalKeys(unsigned char key, int xcoor, int ycoor){
	if (key==ESC){ destructor(); exit(0);}
	if (key=='s' && (fondo.selectscreen==Background::arcade ||fondo.selectscreen==Background:: survival)) 
		{
			save();
			fondo.selectscreen=Background::savedplay; //change to other ending screen !
		}
	//if (key ==' ' && fondo.selectscreen==Background::titlescreen) fondo.selectscreen=Background::introscreen;
	
}

void changeSize(int w, int h) {

        // Prevent a divide by zero, when window is too short
        // (you cant make a window of zero width).
        if (h == 0)
                h = 1;
        float ratio =  w * 1.0 / h;

        // Use the Projection Matrix
        glMatrixMode(GL_PROJECTION);

        // Reset Matrix
        glLoadIdentity();

        // Set the viewport to be the entire window
        glViewport(0, 0, w, h);

        // Set the correct perspective.
        gluPerspective(45.0f, ratio, 0.1f, 100.0f);

        // Get Back to the Modelview
        glMatrixMode(GL_MODELVIEW);
}



void mouse(int button, int state, int x, int y)
{
	if(button==GLUT_LEFT_BUTTON ){
		if(fondo.selectscreen==Background::initscreen) {
			if(x<380 && x>200 && y<390 && y>340){	 //Arcade
				if(state==GLUT_DOWN){
					fondo.selectscreen=Background::arcade;
				}
			}


			if(x<710 && x>560 && y<390 && y>340){	//Survival
				if(state==GLUT_DOWN){
					fondo.selectscreen=Background::survival;
				}
			
			}
	
			if(x<513 && x>397 && y<477 && y>466){	//Settings
				if(state==GLUT_DOWN){
					fondo.selectscreen=Background::settingsscreen;
				
				}
			
			}
		}	
		


		if(fondo.selectscreen==Background::settingsscreen){
			if(x<285 && x>163 && y<247 && y>221){	 //Easy
				if(state==GLUT_DOWN){
					difficulty=1;
					fondo.selectscreen=Background::initscreen;
				}
			}


			if(x<530 && x>388 && y<247 && y>221){	//Normal
				if(state==GLUT_DOWN){
					fondo.selectscreen=Background::initscreen;
					difficulty=2;
				}
			
			}
	
			if(x<755 && x>625 && y<247 && y>221){	//Hard
				if(state==GLUT_DOWN){
					fondo.selectscreen=Background::initscreen;
					difficulty=3;
				}
			}
		}

		if(fondo.selectscreen==Background::introscreen) {
			if(x<713 && x>645 && y<503 && y>485){	 //Arcade
				if(state==GLUT_DOWN){
					fondo.selectscreen=Background::initscreen;
				}
			}	
		}
		
		if(fondo.selectscreen==Background::settingsscreen) { //Load
			if(x<544 && x>370 && y<422 && y>380){
				if(state==GLUT_DOWN){
					load(); 
					loadinggame=true; 
					//fondo.selectscreen=Background::survival;
				}
			}
		}

	if(fondo.selectscreen==Background::titlescreen && state==GLUT_DOWN)  //Title screen
		fondo.selectscreen++; 
	}
}

void mousePassive(int x, int y){
	
	if(fondo.selectscreen==Background::initscreen) {

		if(x<380 && x>200 && y<390 && y>340){	 //Arcade
			fondo.arcadew=3.5;	
			fondo.arcadeh=2;
		}
	
		else if(x<710 && x>560 && y<390 && y>340){	//Survival
			fondo.survivalw=3.5;	
			fondo.survivalh=2;
	
		}
	
		else if(x<513 && x>397 && y<477 && y>466){	//Settings
			fondo.settingsw=2.5;
			fondo.settingsh=1;
	
			
		}

		else{
			fondo.arcadew=3; 
			fondo.arcadeh=1.5;
			fondo.survivalw=3;
			fondo.survivalh=1.5;
			fondo.settingsw=2;
			fondo.settingsh=0.5;
		}
	}

	if(fondo.selectscreen==Background::settingsscreen) {

		if(x<285 && x>163 && y<247 && y>221){	 //Easy
				fondo.notw=3;
				fondo.noth=1.5;
		}


		else if(x<530 && x>388 && y<247 && y>221){	//Normal
			fondo.somewhatw=3;
			fondo.somewhath=1.5;
		}

		else if(x<755 && x>625 && y<247 && y>221){	//Hard
			fondo.veryw=3;
			fondo.veryh=1.5;
		}

		else if(x<544 && x>370 && y<422 && y>380){	//Load
			fondo.loadw=3.5;
			fondo.loadh=2;
		}
	
		else{
			fondo.notw=2.5;
			fondo.noth=1;
			fondo.somewhatw=2.5;
			fondo.somewhath=1;
			fondo.veryw=2.5;
			fondo.veryh=1;
			fondo.loadw=3;
			fondo.loadh=1.5;
		}
	}
}

void writeScore()
{
	float t=1; //score multipliers
	float p=1;
	
	float total=0;
	total= fondo.timer.getTime()*t + player.getPoints()*p;
	
	
	ofstream score("../../High Scores.txt", ofstream::app);
	score<<"Name: "<<player.getName()<<"\tScore: "<<total<<endl;
	score.close();
}


void save()
{
	ofstream save("../src/SaveFile.txt", ofstream::trunc);
	save<<player.getName()<<endl<<fondo.selectscreen<<endl;
	save<<player.getLife()<<endl<<player.getFuel()<<endl<<player.getPoints()<<endl<<fondo.timer.getTime()<<endl<<falling[0]->getSpeed()<<endl;
	save.close();
}



void load()
{
	string name,playmode, life, fuel, points, time, f_speed; 
	ifstream load("../src/SaveFile.txt");
	
	while(load.good())
	{
		getline (load, name);	
		if (name!= "")	
		player.setName(name); 

		getline (load, playmode);	

		getline(load, life); 
		player.setLife(atof(life.c_str()));

		getline(load, fuel);
		player.setFuel(atof(fuel.c_str()));

		getline(load, points);
		player.setPoints(atoi(points.c_str()));

		getline (load, time); 
		fondo.timer.setInitTime(atoi(time.c_str())); 

		getline (load, f_speed); 

		speed=(atof(f_speed.c_str())); 
	}
	
	load.close();
	
	if(atoi(playmode.c_str())==Background::arcade)
		fondo.selectscreen=Background::arcade; 
	
	if(atoi(playmode.c_str())==Background::survival)
		fondo.selectscreen=Background::survival; 
}

void destructor()
{
	for (int i=0; i<falling.size(); i++)
		delete falling[i];
}

